package com.yanqu.xiuxian.crosssystem.manger.elementalbonds.logic;

import com.yanqu.xiuxian.config.elementalbonds.ElementalBondsConfigMgr;
import com.yanqu.xiuxian.config.elementalbonds.ElementalBondsSkillConfig;
import com.yanqu.xiuxian.config.elementalbonds.enums.ElementalBondsEffectType;
import com.yanqu.xiuxian.config.elementalbonds.enums.ElementalBondsOperateType;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsGameData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsPlayerData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsRoomData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsSkillData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.entity.ElementalBondsBlock;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.entity.ElementalBondsOperateEffect;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.enums.ElementalBondsSkillType;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.param.ElementalBondsSkillParam;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.result.ElementalBondsOperateResult;
import com.yanqu.xiuxian.server.protocol.GameErrorCode;

import java.util.Random;
import java.util.Set;

public class ElementalBondsSkillLogic {

    public static ElementalBondsOperateResult operate(ElementalBondsRoomData elementalBondsRoomData, boolean isPlayer1,
                                                      ElementalBondsSkillParam elementalBondsSkillParam, int guideDropNo, int roomRound) {
        ElementalBondsPlayerData elementalBondsPlayerData = isPlayer1 ? elementalBondsRoomData.getPlayer1() : elementalBondsRoomData.getPlayer2();
        ElementalBondsGameData elementalBondsGameData = elementalBondsRoomData.getGameData().clone();
        // 判断本次操作允不允许加步数， （步数满了且不是快速充能技能操作 不允许加步数）
        boolean notAddStep = ElementalBondsGameLogic.isStepMax(elementalBondsRoomData.getModeId(), elementalBondsPlayerData)
                && elementalBondsSkillParam.getSkillId() != ElementalBondsSkillType.SKILL_1003.getType();
        ElementalBondsOperateResult elementalBondsOperateResult = new ElementalBondsOperateResult(ElementalBondsOperateType.USE_SKILL, notAddStep, elementalBondsRoomData.getTurnPlayer());
        elementalBondsOperateResult.setSkillId(elementalBondsSkillParam.getSkillId());
        ElementalBondsSkillConfig elementalBondsSkillConfig = ElementalBondsConfigMgr.getInstance().getSkillConfigMap().get(elementalBondsSkillParam.getSkillId());
        // 检查配置
        if (elementalBondsSkillConfig == null) {
            elementalBondsOperateResult.setRet(GameErrorCode.E_ELEMENTAL_BONDS_SKILL_CONFIG_NO_EXIST);
            return elementalBondsOperateResult;
        }
        // 检查技能
        elementalBondsOperateResult.setRet(check(elementalBondsGameData, elementalBondsPlayerData, elementalBondsSkillParam, elementalBondsOperateResult));
        if (elementalBondsOperateResult.getRet() != GameErrorCode.E_SUCCESS_VALUE) {
            return elementalBondsOperateResult;
        }
        // 补充点参数
        elementalBondsSkillParam.setSide(isPlayer1 ? 1 : 2);
        Random random = new Random();
        // 使用技能
        use(elementalBondsSkillConfig, elementalBondsSkillParam, elementalBondsGameData, elementalBondsOperateResult, elementalBondsPlayerData,
                random, guideDropNo, roomRound, elementalBondsRoomData.getTurnPlayer());
        if (elementalBondsOperateResult.getRet() != GameErrorCode.E_SUCCESS_VALUE) {
            return elementalBondsOperateResult;
        }
        ElementalBondsSceneLogic.operateEnd(random, elementalBondsGameData, elementalBondsOperateResult);
        // 结果
        elementalBondsOperateResult.setElementalBondsGameData(elementalBondsGameData);
        return elementalBondsOperateResult;
    }

    private static int check(ElementalBondsGameData elementalBondsGameData, ElementalBondsPlayerData elementalBondsPlayerData,
                             ElementalBondsSkillParam elementalBondsSkillParam, ElementalBondsOperateResult elementalBondsOperateResult) {
        // 找技能
        ElementalBondsSkillData elementalBondsSkillData = elementalBondsPlayerData.getElementalBondsSkillDataList().stream()
                .filter(skillData -> skillData.getSkillId() == elementalBondsSkillParam.getSkillId())
                .findFirst()
                .orElse(null);
        if (elementalBondsSkillData == null) {
            return GameErrorCode.E_ELEMENTAL_BONDS_SKILL_NO_EXIST;
        }
        // 剩余次数
        if (elementalBondsSkillData.getTimes() <= 0) {
            return GameErrorCode.E_ELEMENTAL_BONDS_SKILL_MAX_TIMES;
        }
        // 特殊技能判断
        ElementalBondsSkillType elementalBondsSkillType = ElementalBondsSkillType.forType(elementalBondsSkillData.getSkillId());
        return elementalBondsSkillType.check(elementalBondsGameData, elementalBondsSkillParam, elementalBondsOperateResult);
    }

    private static void use(ElementalBondsSkillConfig elementalBondsSkillConfig, ElementalBondsSkillParam elementalBondsSkillParam,
                            ElementalBondsGameData elementalBondsGameData, ElementalBondsOperateResult elementalBondsOperateResult, ElementalBondsPlayerData elementalBondsPlayerData,
                            Random random, int guideDropNo, int roomRound, int turnPlayer) {
        // 使用技能
        ElementalBondsSkillType elementalBondsSkillType = ElementalBondsSkillType.forType(elementalBondsSkillParam.getSkillId());
        Set<ElementalBondsBlock> elementalBondsBlockSet = elementalBondsSkillType.use(elementalBondsSkillConfig, elementalBondsSkillParam,
                elementalBondsGameData, elementalBondsOperateResult, elementalBondsPlayerData, random, roomRound, turnPlayer);
        ElementalBondsEliminateLogic.bigEliminate(elementalBondsGameData, elementalBondsPlayerData, null,
                elementalBondsBlockSet, elementalBondsOperateResult, random, guideDropNo, roomRound, turnPlayer);
        // 卡片结束效果
        elementalBondsOperateResult.addElementalBondsOperateEffect(new ElementalBondsOperateEffect(ElementalBondsEffectType.SKILL_END));
    }

}
